Skip to content

Add helpful checks of channel names and PSK#10792

Open
NomDeTom wants to merge 6 commits into
meshtastic:developfrom
NomDeTom:Poka-Yoke
Open

Add helpful checks of channel names and PSK#10792
NomDeTom wants to merge 6 commits into
meshtastic:developfrom
NomDeTom:Poka-Yoke

Conversation

@NomDeTom

@NomDeTom NomDeTom commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

This is the fix for #10764 where a user can think that they have changed presets, but have an explicitly named channel that uses the old preset default name - user on NarrowSlow getting/sending channel messages with hash 0x08 rather than 0x12.

This also fixes the case where a completely blank password is entered rather than AQ==, which again yields an incorrect channel hash (0x0a rather than 0x08 for LongFast, for example) - this is skipped for licensed users.

I have also included a fix for a perennial problem - my inability to remember the difference between LongFast, Longfast, Long Fast, Long fast, long fast and longfast. The firmware checks if a channel name that is lower-cased and stripped of spaces matches the same as the modem preset, and flags this to the user.

If you're on a custom preset, you also get some help to match a channel correctly, although it can't be as exact.

All of these generate phone warnings, but I think they're necessary.

I've tested this, and it generates the warnings as expected.

example log lines:

WRN [Router] Channel 1 name 'nArrOwFast' looks like a mistype of 'NarrowFast' - clear the name to use the preset name automatically.
WRN [Router] Channel 1 name 'nArrOwFast' looks like a mistype of 'NarrowFast' - clear the name to use the preset name automatically.
WRN [Router] Channel 0 'nArrOwfast' matches preset 'NarrowFast' but uses a non-default key - other nodes on this preset cannot decode it.
Screenshot_20260625_175235_Meshtastic Screenshot_20260625_175413_Meshtastic Screenshot_20260625_175204_Meshtastic

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • Seeed Studio T-1000E tracker card
    • Other (please specify below)
      Promicro DIY

Summary by CodeRabbit

  • Bug Fixes
    • Admin warnings for channel and configuration changes are now combined and shown once at commit, reducing duplicate notifications.
    • Licensing-mode notices are now delivered more consistently during edit sessions.
    • Warning messages are now handled more safely when they contain special characters.
    • Channel checks now better detect naming and key conflicts, including when multiple channels are affected.

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

⚡ Try this PR in the Web Flasher

Flash this PR in the Web Flasher

firmware commit boards expires

Warning

This is an automated, unreviewed CI test build. Back up your device configuration
before flashing, and only flash devices you are able to recover.

Supported boards built by this PR (26)
Device Board Platform
Crowpanel Adv 3.5 TFT elecrow-adv-35-tft esp32-s3
Heltec HT62 heltec-ht62-esp32c3-sx1262 esp32-c3
Heltec Mesh Node 096 heltec-mesh-node-t096 nrf52840
Heltec Mesh Node T1 heltec-mesh-node-t1 nrf52840
Heltec Mesh Node T114 heltec-mesh-node-t114 nrf52840
Heltec V3 heltec-v3 esp32-s3
Heltec V4 heltec-v4 esp32-s3
Raspberry Pi Pico pico rp2040
Raspberry Pi Pico W picow rp2040
RAK WisMesh Tag rak_wismeshtag nrf52840
RAK WisBlock 11200 rak11200 esp32
RAK WisBlock 11310 rak11310 rp2040
RAK3312 rak3312 esp32-s3
RAK WisBlock 4631 rak4631 nrf52840
Seeed SenseCAP Mesh-Tracker-X1 seeed_mesh_tracker_X1 nrf52840
Seeed Wio Tracker L1 seeed_wio_tracker_L1 nrf52840
Seeed Xiao NRF52840 Kit seeed_xiao_nrf52840_kit nrf52840
Seeed Xiao ESP32-S3 seeed-xiao-s3 esp32-s3
Station G2 station-g2 esp32-s3
Station G3 station-g3 esp32-s3
LILYGO T-Deck t-deck-tft esp32-s3
LILYGO T-Echo t-echo nrf52840
LILYGO T-Echo Plus t-echo-plus nrf52840
LILYGO T-Impulse Plus t-impulse-plus nrf52840
LilyGo T3-C6 tlora-c6 esp32-c6
Seeed SenseCAP T1000-E tracker-t1000-e nrf52840

Build artifacts expire on 2026-08-05. Updated for b107e94.

@github-actions github-actions Bot added needs-review Needs human review bugfix Pull request that fixes bugs labels Jun 25, 2026
@NomDeTom NomDeTom requested a review from Copilot June 25, 2026 16:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds AdminModule-side validation/warnings to help users avoid channel-name and PSK configurations that unintentionally diverge from modem preset expectations, reducing silent interoperability failures (notably around preset changes and “blank” inputs).

Changes:

  • Emit warnings after a channel is saved to catch blank PSKs (with licensing exceptions) and preset-name/PSK mismatches.
  • Emit warnings after a modem preset change to detect channels still named like the old preset or colliding with the new preset name.
  • Add helper normalization for loose preset-name comparison (case-insensitive, spaces stripped).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
src/modules/AdminModule.h Declares new internal warning helpers for LoRa preset changes and channel updates.
src/modules/AdminModule.cpp Implements normalization + warning logic, and wires warnings into handleSetConfig() and handleSetChannel().

Comment thread src/modules/AdminModule.cpp Outdated
Comment thread src/modules/AdminModule.cpp
Comment thread src/modules/AdminModule.cpp Outdated
Comment thread src/modules/AdminModule.cpp Outdated
Comment thread src/modules/AdminModule.cpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Firmware Size Report

22 targets | vs develop: 21 increased, 1 decreased, net +441,156 (+430.8 KB)

Target Size vs develop
picow 1,274,448 📈 +29,568 (+28.9 KB)
pico2w 1,249,104 📈 +28,588 (+27.9 KB)
rak11310 833,680 📈 +28,256 (+27.6 KB)
pico 810,936 📈 +28,248 (+27.6 KB)
seeed_xiao_rp2040 809,144 📈 +28,240 (+27.6 KB)
Show 17 more target(s)
Target Size vs develop
pico2 797,184 📈 +27,408 (+26.8 KB)
seeed_xiao_rp2350 795,328 📈 +27,392 (+26.8 KB)
t-deck-tft 3,834,480 📈 +23,808 (+23.2 KB)
heltec-vision-master-e213-inkhud 2,249,952 📈 +22,592 (+22.1 KB)
elecrow-adv-35-tft 3,437,808 📈 +21,184 (+20.7 KB)
seeed-xiao-s3 2,294,224 📈 +18,080 (+17.7 KB)
heltec-ht62-esp32c3-sx1262 2,153,024 📈 +18,032 (+17.6 KB)
heltec-v3 2,282,064 📈 +17,984 (+17.6 KB)
rak3312 2,290,032 📈 +17,792 (+17.4 KB)
station-g3 2,284,096 📈 +17,744 (+17.3 KB)
station-g2 2,284,080 📈 +17,728 (+17.3 KB)
rak11200 1,878,208 📈 +17,600 (+17.2 KB)
t-eth-elite 2,508,480 📈 +16,992 (+16.6 KB)
tlora-c6 2,384,784 📈 +16,480 (+16.1 KB)
heltec-v4 2,293,568 📈 +16,272 (+15.9 KB)
wio-e5 241,508 📈 +2,880 (+2.8 KB)
rak3172 184,584 📉 -1,712 (-1.7 KB)

Updated for 623f2a0

@NomDeTom NomDeTom requested review from garthvh and jamesarich July 6, 2026 10:05
@NomDeTom

NomDeTom commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

@garthvh @jamesarich Any views on the wording of the messages? I know you're both able to tweak them in-app, but if they're right here, they're right everywhere.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

AdminModule adds a coalescing warning system that queues channel/config and licensed-mode notifications during edit transactions and flushes a combined message at commit, instead of sending multiple immediate notifications. LoRa preset changes and channel sets now trigger scanners that detect conflicts. Tests validate the new warning/coalescing behavior end-to-end.

Changes

Admin warning coalescing

Layer / File(s) Summary
Warning infrastructure and declarations
src/modules/AdminModule.h, src/modules/AdminModule.cpp (include)
New helper method declarations and member state (queued text, channel bitmask, warning-type flags, pending licensed-mode flag) for coalescing warnings; adds DisplayFormatters.h include.
Core queueing/flush logic and format-string hardening
src/modules/AdminModule.cpp
Implements flushChannelWarnings(), warnLicensedMode(), warnOnChannelSet(), warnOnLoraPresetChange(), preset-name normalization, and hardens sendWarningAndLog to format user text via "%s".
Licensed-mode call sites
src/modules/AdminModule.cpp
handleSetOwner, handleSetChannel, and handleSetHamMode route licensed-mode notices through warnLicensedMode() instead of sending directly.
Channel-set warning wiring
src/modules/AdminModule.cpp
handleSetChannel invokes warnOnChannelSet() after saving and flushes queued warnings outside a transaction; commit_edit_settings flushes queued warnings once per transaction.
LoRa preset-change staging
src/modules/AdminModule.cpp
handleSetConfig records old/new LoRa configs when modem_preset changes, defers the warning, then emits it and flushes queued warnings after save.
Test harness and coalescing test suite
test/test_admin_radio/test_main.cpp
Captures notification text via MockMeshService, exposes handleReceivedProtobuf for tests, adds helpers and new end-to-end tests for single/multi-channel and licensed-mode warning coalescing, and registers new tests in the runner.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AdminModule
  participant ChannelStore as Channel/Config Store
  participant MeshService

  Client->>AdminModule: begin_edit_settings
  Client->>AdminModule: set_channel (multiple)
  AdminModule->>ChannelStore: save channel
  AdminModule->>AdminModule: warnOnChannelSet() queues warning
  Client->>AdminModule: set_config (modem_preset change)
  AdminModule->>ChannelStore: save config
  AdminModule->>AdminModule: warnOnLoraPresetChange() queues warning
  Client->>AdminModule: commit_edit_settings
  AdminModule->>AdminModule: flushChannelWarnings() coalesces queued items
  AdminModule->>MeshService: sendClientNotification (single combined message)
  MeshService-->>Client: notification delivered
Loading

Estimated code review effort: 4 (Complex) | ~60 minutes

Poem

A rabbit taps the config keys,
queues up warnings, takes its ease,
waits till commit, then—one clear shout,
instead of noisy warnings out! 🐇
Channels checked, presets aligned,
one tidy message, well-designed. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the PR's main change: adding warnings/checks for channel names and PSK handling.
Description check ✅ Passed The description explains the bug fix, testing, and includes the attestations section, though some device checkboxes are left unchecked.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
test/test_admin_radio/test_main.cpp (2)

1306-1313: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert total warning count for licensed-immediate test.

Unlike its transactional counterpart (line 1328), this test only checks warningsContaining("Licensed mode activated"), never the total capturedWarnings.size(). It wouldn't catch a regression where an unexpected extra warning (e.g., a spurious channel-name warning) is emitted alongside the licensed notice.

✅ Suggested addition
     sendSetChannel(makeChannel(0, meshtastic_Channel_Role_PRIMARY, "", CUSTOM_KEY, 2));
     TEST_ASSERT_EQUAL_INT(1, warningsContaining("Licensed mode activated"));
+    TEST_ASSERT_EQUAL_INT(1, (int)capturedWarnings.size());
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_admin_radio/test_main.cpp` around lines 1306 - 1313, The
licensed-immediate test only verifies warningsContaining("Licensed mode
activated"), so it can miss extra warnings emitted by sendSetChannel() or
ensureLicensedOperation(). Update
test_warn_license_noTransaction_emittedImmediately to also assert the total
capturedWarnings.size() matches the expected single warning, mirroring the
transactional test’s stronger check.

1170-1223: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Trim the multi-line banner comment.

The 8-line section-header comment exceeds the "one or two lines at most" limit for code comments. The rest of the helpers (warningsContaining, makeChannel, sendAdmin, etc.) look correct.

✏️ Suggested trim
-// -----------------------------------------------------------------------
-// Channel-configuration warning + coalescing tests
-//
-// These exercise the real incoming-admin-message path (handleReceivedProtobuf):
-// begin_edit_settings / set_channel / commit_edit_settings. Warnings raised while a
-// transaction is open must be deferred and collapsed into a single notification at
-// commit; outside a transaction each save emits its own single message immediately.
-// -----------------------------------------------------------------------
+// Channel-configuration warning + coalescing tests: exercises the real incoming-admin
+// path (begin/set_channel/commit) where transaction-scoped warnings must collapse to one.

As per coding guidelines, "Keep code comments minimal: one or two lines at most, only explain the why when it is not obvious, and avoid multi-paragraph explanatory comments."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_admin_radio/test_main.cpp` around lines 1170 - 1223, Trim the
section-header comment above the channel-configuration warning/coalescing test
helpers so it is no more than one or two lines. Keep the intent clear but remove
the long explanatory banner, leaving the helper functions like
warningsContaining, makeChannel, sendAdmin, and sendSetChannel unchanged.

Source: Coding guidelines

src/modules/AdminModule.cpp (1)

1965-1981: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Trim the multi-paragraph doc comments to satisfy the repo comment style.

Both warnOnChannelSet (this block) and warnOnLoraPresetChange (Lines 2089-2106) carry multi-paragraph explanatory comments. The check logic here is already self-explanatory; condense each to a one/two-line summary of the why.

As per coding guidelines for **/*.{cpp,h}: "Keep code comments minimal: one or two lines at most, only explain the why when it is not obvious, and avoid multi-paragraph explanatory comments."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/modules/AdminModule.cpp` around lines 1965 - 1981, Trim the long Doxygen
block above warnOnChannelSet to a one- or two-line comment that only captures
the essential why, and do the same for warnOnLoraPresetChange; remove the
multi-paragraph bullet list and detailed scenario explanations so the comments
match the repo style while keeping the intent clear.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/modules/AdminModule.cpp`:
- Around line 1965-1981: Trim the long Doxygen block above warnOnChannelSet to a
one- or two-line comment that only captures the essential why, and do the same
for warnOnLoraPresetChange; remove the multi-paragraph bullet list and detailed
scenario explanations so the comments match the repo style while keeping the
intent clear.

In `@test/test_admin_radio/test_main.cpp`:
- Around line 1306-1313: The licensed-immediate test only verifies
warningsContaining("Licensed mode activated"), so it can miss extra warnings
emitted by sendSetChannel() or ensureLicensedOperation(). Update
test_warn_license_noTransaction_emittedImmediately to also assert the total
capturedWarnings.size() matches the expected single warning, mirroring the
transactional test’s stronger check.
- Around line 1170-1223: Trim the section-header comment above the
channel-configuration warning/coalescing test helpers so it is no more than one
or two lines. Keep the intent clear but remove the long explanatory banner,
leaving the helper functions like warningsContaining, makeChannel, sendAdmin,
and sendSetChannel unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2fc04ea9-f83e-4052-854c-24b79ad1f0b2

📥 Commits

Reviewing files that changed from the base of the PR and between fe6bf91 and b107e94.

📒 Files selected for processing (3)
  • src/modules/AdminModule.cpp
  • src/modules/AdminModule.h
  • test/test_admin_radio/test_main.cpp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs needs-review Needs human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants